import React from 'react';
import produce from 'immer';
import { Upload, notification, message, Button } from 'antd';
import { formatMessage } from 'umi';
import { LoadingOutlined, UploadOutlined, AlertOutlined, CheckOutlined } from '@ant-design/icons';
import { getToken } from '@/zero/utils/token';

/**
 * accept: 'application/msword, .docx'
 */
const Index = (props) => {
  const {
    multiple = true, // 是否支持多选文件，ie10+ 支持。开启后按住 ctrl 可选择多个文件
    name = 'file', // 发到后台的文件参数名（Upload 组件批量上传的实现方式是“单个文件的依次上传”，所以使用“file”）

    disabled = false,
    headers, // 设置上传的请求头部，IE10 以上有效
    beforeUpload = () => true,

    accept = 'text/plain, .pdf, .doc, .docx, .xls, .xlsx, .ppt, .pptx, .rtf, .csv, .xml, .xlf, .zip, .rar, .png, .gif, .jpeg, .jpg, .svg', // 接受上传的文件类型，（MIME 类型，http://www.iana.org/assignments/media-types/media-types.xhtml）,
    buttonTitle,

    action, // 上传地址 => https://www.mocky.io/v2/5cc8019d300000980a055e76
    feedback = true, // 反馈 => action 存在时可用

    defaultFileList = [],

    onFileComplete = (file) => {
      console.log('onFileComplete', file);
    },
    onFileError,
    onAllComplete = (files) => {
      console.log('onAllComplete', files);
    },

    onChange, // 上传文件改变时的状态

    children,

    ...rest
  } = props;

  let authorities = []; // 文件uid列表 => 单次上传

  const extProps = produce({}, (draftState) => {
    draftState.headers = {
      Authorization: getToken(),
      ...headers,
    };
    draftState.beforeUpload = (newFile, newFileList) => {
      authorities = newFileList.map((item) => item.uid);

      const isTrue = beforeUpload(newFile, newFileList);
      if (isTrue && !action) {
        onFileComplete(newFile);
        if (newFileList.length >= 1 && newFileList[newFileList.length - 1].uid === newFile.uid) {
          onAllComplete(newFileList);
        }
        return false;
      }
      return isTrue && action;
    };
    return draftState;
  });

  return (
    <>
      <Upload
        multiple={multiple}
        name={name}
        showUploadList={false}
        disabled={disabled}
        accept={accept}
        action={action}
        defaultFileList={defaultFileList}
        {...rest}
        {...extProps}
        onChange={(info) => {
          const { file: newFile, fileList: newFileList } = info; // 当前操作的文件对象， 当前的“上传文件列表”

          if (action) {
            const finalFileList = newFileList.filter((item) => authorities.includes(item.uid));

            const updateFeedback = (results = [], extOption = {}) => {
              if (results.length) {
                notification.open({
                  key: 'KEY_UPLOAD',
                  duration: 0,
                  ...extOption,
                  style: {
                    width: 500,
                    marginLeft: 384 - 500,
                  },
                  message: formatMessage({ id: '上传结果' }),
                  ...feedback,
                  description: feedback.renderItems
                    ? feedback.renderItems(results)
                    : results.map((item, index) => (
                        <div style={{ marginBottom: 5 }} key={index}>
                          {item.status === 'done' &&
                            (feedback.renderItemDone ? (
                              feedback.renderItemDone(item)
                            ) : (
                              <>
                                <CheckOutlined
                                  style={{ color: '#52c41a' }}
                                  title={formatMessage({ id: '上传成功' })}
                                />
                                &nbsp;&nbsp;{item.name}
                              </>
                            ))}
                          {item.status === 'error' &&
                            (feedback.renderItemError ? (
                              feedback.renderItemError(item)
                            ) : (
                              <>
                                <AlertOutlined
                                  style={{ color: '#f5222d' }}
                                  title={formatMessage({ id: '上传失败' })}
                                />
                                &nbsp;&nbsp;{item.name}
                                {item.response?.message && (
                                  <>
                                    &nbsp;-&nbsp;
                                    <span style={{ color: '#f5222d' }}>
                                      {item.response.message}
                                    </span>
                                  </>
                                )}
                              </>
                            ))}
                          {item.status === 'uploading' &&
                            (feedback.renderItemUploading ? (
                              feedback.renderItemUploading(item)
                            ) : (
                              <>
                                <LoadingOutlined title={formatMessage({ id: '正在上传' })} />
                                &nbsp;&nbsp;{`${item.name} - ${parseInt(item.percent, 10)}%`}
                              </>
                            ))}
                        </div>
                      )),
                });
              }
            };

            switch (newFile.status) {
              case 'uploading':
                if (feedback) {
                  updateFeedback(finalFileList);
                }
                break;
              case 'done':
                if (feedback) {
                  updateFeedback(finalFileList);
                }
                onFileComplete(newFile);
                if (finalFileList.every((item) => item.status === 'done')) {
                  if (feedback) {
                    updateFeedback(finalFileList, { duration: 3.5 });
                  }
                  onAllComplete(finalFileList);
                }
                break;
              case 'error':
                if (feedback) {
                  updateFeedback(finalFileList, {
                    onClose: () => {
                      onAllComplete(finalFileList);
                    },
                  });
                }
                if (onFileError) {
                  onFileError(newFile);
                }
                break;
              case 'removed':
                if (feedback) {
                  message.success({
                    key: newFile.name,
                    duration: 7,
                    content: `${newFile.name} - ${formatMessage({ id: '删除成功' })}`,
                  });
                }
                break;
              default:
                console.log(`${newFile.name} - ${formatMessage({ id: '未知异常' })}`);
                break;
            }
          }

          const effectiveFileList = newFileList.filter(
            (item) =>
              item.status === 'uploading' ||
              (['done', 'error'].includes(item.status) && item.response), // 按照服务器返回信息筛选有效的上传文件
          );

          const newEffectiveFileList = effectiveFileList.map((item) => {
            const { response } = item;
            if (response) {
              return {
                ...item,
                url: response.url,
                thumbUrl: response.url,
              };
            }
            return item;
          });

          if (onChange) {
            onChange(newEffectiveFileList);
          }
        }}
      >
        {React.cloneElement(
          children || (
            <Button type="primary" title={buttonTitle || accept} style={{ marginBottom: 12 }}>
              <UploadOutlined />
              {formatMessage({ id: '上传附件' })}
            </Button>
          ),
          { disabled },
        )}
      </Upload>
    </>
  );
};

Object.keys(Upload).forEach((item) => {
  if (!['defaultProps', 'propTypes'].includes(item)) {
    Index[item] = Upload[item];
  }
});
Index.displayName = 'Upload';
export default Index;
